/**
 *
 *
 * \file SpeedCtrlClient.i
 * \brief Python bindings for following by Tapio Taipalus <tapio.taipalus@tkk.fi>
 * \file SpeedCtrlClient.hpp
 * \brief MaCI - Ranging Interface Client module header
 * \author Antti Maula <antti.maula@tkk.fi>
 * 
 * \todo The GetDevicePosition and GetDeviceLimits functions are unimplemented.
 */

%module SpeedCtrlClient

//%include "typemaps.i"
%include "../MaCIError.i"
%include "../common/timestamp.i"
%include "../MaCICtrl/MaCICtrlClient.i"

%{
#include "MaCI.hpp"
#include "thread.hpp"
#include "sync.hpp"
#include "SpeedCtrlTypes.hpp"
#include "SpeedCtrlData.hpp"
#include "SpeedCtrlClient.hpp"
#include "timestamp.hpp"
%}

// Forward declare gimi::GIMI
namespace gimi {
  class GIMI;
}

namespace MaCI {
  namespace SpeedCtrl {
/*
    enum ESpeedCtrlReply { 
      KReplyIntervals = 0,  
      KReplySpeeds    = 1,
      KEventSpeedData = 2
    };
*/
    /** MaCI - SpeedCtrl Client interface.
     * 
     * This class contains the methods and types for using
     * a MaCI::SpeedCtrl service in the GIMnet.
     */
    class CSpeedCtrlClient : private gim::CSync,
                             private gim::CThread,
                             public MaCI::CMaCI
    {
    public:
      /** Constructor.
       * 
       * Constructor of the SpeedCtrlClient. This requires;
       * a pointer to Initialized and connected GIMI, minor
       * number of this interface (Used as GIMI minor number)
       *
       * @param[in] aGIMIPtr Pointer to GIMI used for communication
       * @param[in] aInterfaceMinor Interface minor number. Usually
       *            used to indicate the instance of devices of same
       *            type.
       */     
      CSpeedCtrlClient(gimi::GIMI *aGIMIPtr, const int aInterfaceMinor = -1);

      
      /** Destructor.
       */
      ~CSpeedCtrlClient();
      

      /** Open client interface.
       */
      MaCI::EMaCIError DoOpen(void);


      /** Close client interface.
       */
      MaCI::EMaCIError DoClose(void);

      
      /** Set speed.
       *
       * This function sends a command attempting to set the servers
       * speed, angularspeed and acceleration values.
       * 
       * @param[in] aSpeed      Speed (m/s)
       * @param[in] aAngularSpeed Angular speed (rad/s (positive CCW))
       * @param[in] aAcceleration Acceleration (m/s^2)
       * @return                'true' if the command was succesfully
       *                        _sent_. Note that the return result 'true' does not
       *                        necessarily mean that the command is
       *                        really received and executed by the server.
       *                        'false' in case the send failed for some reason.
       *                        (No such client, no connection, etc.)
       */
      bool SetSpeed(const float aSpeed, const float aAngularSpeed, const float aAcceleration);
      
      
      /** Stop.
       *
       * This function sends a command attempting to stop the server
       * as fast as possible. It depends on the hardware
       * implementation on how fast it may stop, but with this command
       * it should break by any means possible.
       *
       * @return                'true' if the command was succesfully
       *                        _sent_. Note that the return result 'true' does not
       *                        necessarily mean that the command is
       *                        really received and executed by the server.
       *                        'false' in case the send failed for some reason.
       *                        (No such client, no connection, etc.)
       */
      bool SetStop(void);


      /**Get Speed limits
       * 
       * This functions saves the max and min speed supported by the server.
       * 
       *
       * @param[out] aMaxSpeeds Pointer to TSpeed-struct where the maximum
       *                        speeds are saved.
       * @param[out] aMinSpeeds Pointer to TSpeed-struct where the minimum
       *                        speeds are saved.
       * @return                TRUE if max and min speeds are known, else
       *                        FALSE
       */
      bool GetSpeedLimits(MaCI::SpeedCtrl::TSpeed &aMaxSpeeds, MaCI::SpeedCtrl::TSpeed &aMinSpeeds);

      /** Start Getting speed event
       *
       * This fuction subscribes to SpeedCtrl server and starts to get
       * speed values that has been set to SpeedCtrlServer. Call this
       * to get speed values from GetSpeed-function.
       * 
       * NOTE: It's not opened by default to avoid big amount of perhaps 
       * unuseful messages. So use it if you really need the information.
       *
       * 
       * @return                TRUE if subscribing to service succeed
       *                        else FALSE(timeout, error,already subscribed..)
       */
      bool StartGettingSpeedEvent(void);

      /** Stop getting speed event
       *
       * This function unsubscribes from SpeedCtrlServer and stop to get
       * speed values from server.
       *
       * @return                TRUE if unsubscribing succeed else FALSE
       */
      bool StopGettingSpeedEvent(void);


      /** Get Speed
       *
       * This function returns speeds that has been set to the server.
       * You must call StartGettingSpeedEvent-function to get this 
       * work
       * 
       * @param aSpeed          Speed (m/s) set to server is saved here
       * @param aAngularSpeed   Angular speed (rad/s (positive CCW)) set to
       *                        server is saved here
       * @param aAcceleration   Acceleration (m/s�) set to server is saved
       *                        here
       * @param aTimestamp      Timestamp of current speed is saved here
       * @param aSequence       Pointer to sequence number. If this is NULL,
       *                        the most recent position is returned immediately.
       *                        If this is not NULL, the value pointed
       *                        should be set to -1 on the first call to this function.
       *                        After each call, the sequence number of the returned
       *                        data is stored here. If user wants to read all the
       *                        measures available, this value should not be
       *                        modified after the first call.
       * @param aTimeout_ms     Timeout to wait the response
       * @return                TRUE if got response from the server within timeout
       *                        time, else FALSE
       */
      bool GetSpeed(float &INOUT, 
                    float &INOUT, 
                    float &INOUT,
                    MaCI::Common::TTimestamp &aTimestamp,
                    int *aSequence, 
                    unsigned int aTimeout_ms);

      /** Get SpeedCtrl Server Timeout time
       *
       * This function returns the timeout time that has been set 
       * to SpeedCtrl Server. If no command has arrived to SpeedCtrlServer
       * within this time, server side generates a timeout-Command when an
       * emergency activity is started. Usually it means that the robot 
       * will stop.
       *
       * @param[out] aServerTimeoutTime Timeout time will be stored here
       * @param aTimeout_ms             Timeout to wait the response
       * @return                        TRUE if got response from the server within timeout
       *                                time, else FALSE
       */
      bool GetSpeedCtrlServerTimeoutTime(ownTime_ms_t &INOUT,
                                         unsigned int aTimeout_ms);




      // Derived from MaCI
//      MaCI::EMaCIError DoOpen(void);
//      MaCI::EMaCIError DoClose(void);

      //Derived from MaCICtrl
        
      
      // Derived from MaCI::CMaCI
	    MaCI::EMaCIError Open();
	    MaCI::EMaCIError Close();    
	  //  void SetMaCICtrlServer(MaCI::MaCICtrl::CMaCICtrlServer *aMaCICtrlServer);
	    void SetDefaultTarget(const std::string &aDefaultTarget, const unsigned int aTimeout_ms = 2000);
	    void SetStaticLinkDelay(const unsigned int aDelay_ms);
	    bool SetGroupName(const std::string &aGroupName);
		bool SetDefaultTarget(const MaCI::MaCICtrl::SMaCISL &aMaCISL, const unsigned int aTimeout_ms = 2000);

    };
  }
}

